﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;

namespace CommonLib
{
	public abstract class AssetFileBase : AssetFile
	{
		public AssetFileBase() {


		}

		public string ID { get; set; }
		public AssetFileLoadPriority Priority { get; protected set; }
		public AssetFileType Type { get; protected set; }
		public AssetLoadError ErrorMessage { get; protected set; }

		public bool IsError { get; protected set; }

		public bool IsComplete { get; protected set; }

		public bool IgnoreUnload { get; protected set; }


		public int ReferenceCount {
			get {
				if (ReferenceObjectSet.Contains(null))
				{
					ReferenceObjectSet.RemoveWhere((obj) => { return obj == null; });
					Debug.LogError("应用为空");
				}
				return ReferenceObjectSet.Count;
			}
		}
		protected HashSet<UnityEngine.Object> ReferenceObjectSet = new HashSet<UnityEngine.Object>();

		protected UnityEngine.Object resource;


		public T GetFile<T>() where T : UnityEngine.Object
		{
			if(VerifyType(typeof(T)))
			{
				Debug.LogError("提取资源错误");
				return default;
			}
			return (T)resource;
		}

		public void RfAdd(UnityEngine.Object obj)
		{
			if(null != obj)
				ReferenceObjectSet.Add(obj);
		}

		public void RfRemove(UnityEngine.Object obj)
		{
			if(obj != null)
				ReferenceObjectSet.Remove(obj);
		}

		/// <summary>
		/// 监听物体物体 销毁时清除引用标记
		/// </summary>
		/// <param name="link"></param>
		public void AddReferenceComponent(GameObject link)
		{
			ReferenceListener rl = link.AddComponent<ReferenceListener>();
			rl.Init(this);
		}



		public void LoadPlaceHolder(AssetFilePlaceHolder placeHolder)
		{
			IsComplete = true;
			IsError = false;
			IgnoreUnload = true;
			if (Type == AssetFileType.None)
				return;

			switch (Type) {
				case AssetFileType.Texture:
					resource = placeHolder.texture;
					break;
				case AssetFileType.Sound:
					resource = placeHolder.audioClip;
					break; 
				case AssetFileType.Movie:
					resource = placeHolder.videoClip;
					break;
				case AssetFileType.Text:
					resource = placeHolder.textAsset;
					break;
				case AssetFileType.UnityObject:
				default:
					resource = placeHolder.UnityObject;
					break;
			}

		}


		protected bool VerifyType(Type type)
		{
			switch (Type) {
				case AssetFileType.None:
					return false;
				case AssetFileType.Texture:
					return typeof(Texture2D) == type;
				case AssetFileType.Sound:
					return typeof(AudioClip) == type;
				case AssetFileType.Movie:
					return typeof(VideoClip) == type;
				case AssetFileType.Text:
					return typeof(TextAsset) == type;
				case AssetFileType.UnityObject:
				default:
					return true;
			}

		}

		public abstract bool CheckCacheOrLocal();
		public abstract IEnumerator LoadAsync(Action onComplete, Action onError);
		public abstract void Unload();
	}
}